#include <stdio.h>
#include <stdlib.h>

#define N  20000000
#define SIZE 200000

// Random /////////////////////////////////////////////////////////////////////

#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <bits/libc-lock.h>

#define TYPE_0          0
#define BREAK_0         8
#define DEG_0           0
#define SEP_0           0

#define TYPE_1          1
#define BREAK_1         32
#define DEG_1           7
#define SEP_1           3

#define TYPE_2          2
#define BREAK_2         64
#define DEG_2           15
#define SEP_2           1

#define TYPE_3          3
#define BREAK_3         128
#define DEG_3           31
#define SEP_3           3

#define TYPE_4          4
#define BREAK_4         256
#define DEG_4           63
#define SEP_4           1

#define MAX_TYPES       5       /* Max number of types above.  */

static int32_t randtbl[DEG_3 + 1] =
  {
    TYPE_3,

    -1726662223, 379960547, 1735697613, 1040273694, 1313901226,
    1627687941, -179304937, -2073333483, 1780058412, -1989503057,
    -615974602, 344556628, 939512070, -1249116260, 1507946756,
    -812545463, 154635395, 1388815473, -1926676823, 525320961,
    -1009028674, 968117788, -123449607, 1284210865, 435012392,
    -2017506339, -911064859, -370259173, 1132637927, 1398500161,
    -205601318,
  };

static int32_t *fptr = &randtbl[SEP_3 + 1];
static int32_t *rptr = &randtbl[1];
static int32_t *state = &randtbl[1];
static int32_t *end_ptr = &randtbl[sizeof (randtbl) / sizeof (randtbl[0])];

unsigned int cp_random ()
  {
    int32_t retval;
    int32_t val;

    val = *fptr += *rptr;
    retval = (val >> 1) & 0x7fffffff;
    ++fptr;
    if (fptr >= end_ptr)
      {
        fptr = state;
        ++rptr;
      }
    else
      {
        ++rptr;
        if (rptr >= end_ptr)
          rptr = state;
      }

    return retval;
  }

// Popul //////////////////////////////////////////////////////////////////////

static const unsigned char BitsSetTable256[256] =
{
#   define B2(n) n,     n+1,     n+1,     n+2
#   define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2)
#   define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2)
    B6(0), B6(1), B6(1), B6(2)
};

static struct num_pop {
    unsigned char d;
    unsigned char c;
    unsigned char b;
    unsigned char a;
    unsigned char pop;
} buffer[SIZE];

int main(int argc, char *argv[])
{
    unsigned int r, i, j, n;
    unsigned char k[4];
    unsigned int* kp = (int*) k;
    if (argc == 1) n = N; else n = atoi(argv[1]);
    for (i = 0; i < n; )
    {
        for (j = 0; j < SIZE; j++)
        {
            r = cp_random();
            *((int*) &buffer[j]) = *kp = r;
            buffer[j].pop = BitsSetTable256[k[0]] +
                            BitsSetTable256[k[1]] +
                            BitsSetTable256[k[2]] +
                            BitsSetTable256[k[3]];
        }
        write(1, buffer, sizeof(buffer));
        i += SIZE;
    }
    return 0;
}

// Original ///////////////////////////////////////////////////////////////////

// int main(int argc, char *argv[])
// {
//     unsigned int k, k_saved, i, n;
//     unsigned char pop;
//     if (argc == 1) n = N; else n = atoi(argv[1]);
//     for (i=0; i<n; i++)
//     {
//         k = k_saved = rand();
//         pop = 0;
//         while (k > 0)
//         {
//             if (k % 2) pop++;
//             k = k >> 1;
//         }
//         fwrite(&k_saved, sizeof(k_saved), 1, stdout);
//         fwrite(&pop, sizeof(pop), 1, stdout);
//     }
//     return 0;
// }
